//package com.hydra.auth.config;
//
//import com.hydra.auth.annotation.AnonymousAccess;
//import com.hydra.auth.common.UserRoleEnum;
//import com.hydra.base.utils.SpringUtils;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.ApplicationArguments;
//import org.springframework.boot.ApplicationRunner;
//import org.springframework.security.access.ConfigAttribute;
//import org.springframework.security.access.SecurityConfig;
//import org.springframework.security.web.FilterInvocation;
//import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
//import org.springframework.stereotype.Component;
//import org.springframework.web.method.HandlerMethod;
//import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
//import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
//import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
//
//import javax.annotation.Resource;
//import java.lang.annotation.Annotation;
//import java.util.*;
//
///**
// * 自定义权限匹配规则
// * @Author 陈煜敏
// * @Date 2022/9/2 15:51
// */
//@Slf4j
//@Component
//public class SecurityMetadataSource implements FilterInvocationSecurityMetadataSource, ApplicationRunner {
//
//    /**开放接口*/
//    private final List<String> permitAll = Arrays.asList(
//            "/error",
//            "/api/auth/login",
//            "/api/auth/temporaryLogin",
//            "/api/auth/register",
//            "/oauth/token"
//    );
//
//    /**配置了注解的url*/
//    private List<String> annotationAnonymousUrls;
//
//    @Resource
//    private PermissionUrlConfig permissionUrlConfig;
//
//    @Override
//    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
//        if(object instanceof FilterInvocation){
//            //获取请求的url
//            String requestUrl = ((FilterInvocation) object).getRequestUrl();
//
//            //开放所有权限
//            List<String> anonymous = permissionUrlConfig.getAnonymous();
//            if(permitAll.contains(requestUrl)
//                    || (anonymous != null && anonymous.contains(requestUrl))
//                    || annotationAnonymousUrls.contains(requestUrl)){
//                return this.createPermission(UserRoleEnum.ROLE_ANONYMOUS);
//            }
//            //开放临时权限
//            List<String> temporary = permissionUrlConfig.getTemporary();
//            if(temporary != null && temporary.contains(requestUrl)){
//                return this.createPermission(UserRoleEnum.ROLE_TEMPORARY_USER);
//            }
//            //管理员权限
//            List<String> admin = permissionUrlConfig.getAdmin();
//            if(admin != null && admin.contains(requestUrl)){
//                return this.createPermission(UserRoleEnum.ROLE_ADMIN);
//            }
//        }
//        //最低也需要具备的客户端用户权限
//        return this.createPermission(UserRoleEnum.ROLE_APP_USER);
//    }
//
//    private Collection<ConfigAttribute> createPermission(UserRoleEnum role){
//        return SecurityConfig.createList(role.getCode());
//    }
//
//    @Override
//    public Collection<ConfigAttribute> getAllConfigAttributes() {
//        return null;
//    }
//
//    @Override
//    public boolean supports(Class<?> clazz) {
//        return false;
//    }
//
//    @Override
//    public void run(ApplicationArguments args) {
//        this.annotationAnonymousUrls = this.getAnnotationAnonymousUrls();
//        log.info("加载到配置开放权限：{}", annotationAnonymousUrls);
//    }
//
//    /**
//     * 获取标有注解 AnonymousAccess 的访问路径
//     */
//    private List<String> getAnnotationAnonymousUrls() {
//        // 获取所有的 RequestMapping
//        Map<RequestMappingInfo, HandlerMethod> handlerMethods = SpringUtils.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
//        List<String> allAnonymousAccess = new ArrayList<>();
//        // 循环 RequestMapping
//        for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethods.entrySet()) {
//            RequestMappingInfo key = infoEntry.getKey();
//            HandlerMethod value = infoEntry.getValue();
//            //开放权限AnonymousAccess
//            Set<String> anonymousUrl = this.getMatchUrl(key, value, AnonymousAccess.class);
//            allAnonymousAccess.addAll(anonymousUrl);
//        }
//        return allAnonymousAccess;
//    }
//
//
//    /**获取配置响应权限的url*/
//    private <T extends Annotation> Set<String> getMatchUrl(RequestMappingInfo key, HandlerMethod value, Class<T> tClass){
//        // 获取controller上的注解
//        Annotation anonymousInBean = value.getBeanType().getAnnotation(tClass);
//        // 获取方法上的注解
//        Annotation anonymousInMethod = value.getMethodAnnotation(tClass);
//        // 如果类或方法上标注了该注解，就获取该方法的访问全路径
//        if (anonymousInBean != null || anonymousInMethod != null) {
//            PatternsRequestCondition patternsCondition = key.getPatternsCondition();
//            if(patternsCondition != null){
//                return patternsCondition.getPatterns();
//            }else{
//                Set<String> patternValues = key.getPatternValues();
//                if(!patternValues.isEmpty()){
//                    return patternValues;
//                }
//            }
//        }
//        return new HashSet<>();
//    }
//
//}
